;BytePairEncoded Recursive

 =============================================================================
;   TextEngine_LoadString: Loads a string
;   In:      Pointer to text statement to load in A (lo) and Y (hi)
;   Out:     Writes string and list of chars used by string
;   Notes:   A,X,Y are wiped out
;         9 temp bytes in zp
_TextEngine_LoadStringToMemory:
.scope
; temp variables in zp
.alias   _stringLength       $00
.alias   _numChars            $01
.alias   _Recursion           $02
.alias   _TempA               $03
.alias   _StringPtr           $04
.alias   _BPE_Left            $06
.alias   _BPE_Right           $08
; these constants are true for strings with characters from 0x00 - 0x60
.alias   _HighR               $ff
.alias   _LowR                $61
; Load the string and decompress it into RAM
   sta _StringPtr                     ; Save address of the string.
   sty _StringPtr+1                   ;   +
   lda #<[$c000-[_HighR-_LowR+1]*2]   ; Get pointer to BPE_Left
   sta _BPE_Left                      ;   |
   lda #>[$c000-[_HighR-_LowR+1]*2]   ;   |
   sta _BPE_Left+1                    ;   +
   lda #<[$c000-[_HighR-_LowR+1]]     ; Get pointer to BPE_Right
   sta _BPE_Right                     ;   |
   lda #>[$c000-[_HighR-_LowR+1]]     ;   |
   sta _BPE_Right+1                   ;   +
   ldx #$01                           ; X is index of current decoded byte
   ldy #$00                           ; Y is index of current encoded byte
   sty _Recursion                     ; Recursion = 0
   lda (_StringPtr),y                 ; Save length of encoded data
   sta _numChars                      ;   +
_getCode:
   cpy _numChars                      ; IF Y == Num Encoded Bytes
   beq _return                        ; THEN all data is decoded, return
   iny                                ; y++
   lda (_StringPtr),y                 ; A = an encoded byte
_decode:
   cmp #_LowR                         ; IF A < LowR
   bcc _writeCode                     ; THEN goto WriteCode ELSE decode byte
   sbc   #_LowR                       ; A = A - _LowR. Carry is already set.
   sta _TempA                         ; Save Y
   tya                                ;   |
   pha                                ;   |
   lda _TempA                         ;   +
   pha                                ; Save A
   tay                                ; Y = A
   inc _Recursion                     ; Recursion++
   lda (_BPE_Left),y                  ; A = BPE_LEFT[Y]
   jsr _decode                        ; Decode this byte
   pla                                ; Restore A
   tay                                ; Y = A
   lda (_BPE_Right),y                 ; A = BPE_RIGHT[Y]
   jsr _decode                        ; Decode this byte
   pla                                ; Restore Y
   tay                                ;   +
   dec _Recursion                     ; Recursion--
   beq _getCode                       ; IF (Recursion == 0) THEN get next code
_return:
   rts                                ; ELSE return to recursion thread
_writeCode:
   sta TEXT_String,x                  ; TEXT_String[x] = a
   inx                                ; x++
   lda _Recursion                     ; IF (Recursion == 0)
   beq _getCode                       ; THEN get next code
   rts                                ; ELSE return to recursion thread